package com.winning.pmph.service;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.beust.jcommander.internal.Maps;
import com.winning.pmph.entity.IncreaseBook;
import com.winning.pmph.entity.IncreaseCategory;
import com.winning.pmph.entity.IncreaseQrCode;
import com.winning.pmph.entity.IncreaseResource;
import com.winning.pmph.entity.KnowledgeLib;
import com.winning.pmph.enumeration.KnowledgeSystem;
import com.winning.pmph.mapper.IncreaseBookMapper;
import com.winning.pmph.mapper.IncreaseCategoryMapper;
import com.winning.pmph.utils.FfmpegUtil;
import com.winning.pmph.utils.PMPHAppUtil;
import com.winning.pmph.utils.RocketMQProducerUtil;
import com.winning.pmph.vo.CategorySelectVo;
import com.winning.pmph.vo.CategoryVo;

import cn.hutool.core.date.DateUtil;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lbm
 * @since 2021-12-30
 */
@Service
public class IncreaseCategoryService extends ServiceImpl<IncreaseCategoryMapper, IncreaseCategory> {
	@Autowired
	IncreaseBookMapper increaseBookMapper;
	@Autowired
	KnowledgeSyncStatusService knowledgeSyncStatusService;
	
	public void addCate(IncreaseCategory increaseCategory) {
		String pid = increaseCategory.getPid();
		String bookId = increaseCategory.getBookId();
		int cateLevel = 1;
		if(!pid.equals(bookId)) {
			IncreaseCategory cate = this.getById(pid);
			Integer cateTempLevel = cate.getCateLevel();
			cateLevel = cateTempLevel+1;
		}
		QueryWrapper<IncreaseCategory> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("pid", pid);
		queryWrapper.orderByDesc("order_num");
		List<IncreaseCategory> list= this.baseMapper.selectList(queryWrapper);
		int orderNum = 1;
		if(list!=null && list.size()>0) {
			IncreaseCategory temp= list.get(0);
			orderNum = temp.getOrderNum()+1;
		}
		increaseCategory.setOrderNum(orderNum);
		increaseCategory.setCateLevel(cateLevel);
		increaseCategory.setCreateTime(new Date());
		increaseCategory.setUpdateTime(new Date());
		increaseCategory.setCreateBy(PMPHAppUtil.getCurrentUserEnName());
		increaseCategory.setUpdateBy(PMPHAppUtil.getCurrentUserEnName());
		this.baseMapper.insert(increaseCategory);
	}
	
	public void upOrDownCate(String cateId,int upDownFlag) {
		IncreaseCategory increaseCategory = this.baseMapper.selectById(cateId);
		String pid = increaseCategory.getPid();
		List<IncreaseCategory> list= getCateListByPid(pid);
		
		
		IncreaseCategory temp = null;
		IncreaseCategory currData = null;
		for (int i = 0; i < list.size(); i++) {
			currData = list.get(i);
			if(currData.getId().equals(cateId)) {
				if(upDownFlag==1 && i > 0) {
					temp = list.get(i-1);
				}else if(upDownFlag == 2 && i < list.size() - 1) {
					temp = list.get(i+1);
				}
				break;
			}
		}
		if(temp==null){
        	return;
        }
		Integer tempSort = temp.getOrderNum();
        Integer currSort = currData.getOrderNum();

        temp.setOrderNum(currSort);
        currData.setOrderNum(tempSort);
        
        this.baseMapper.updateById(temp);
        this.baseMapper.updateById(currData);
	}
	
	public IncreaseCategory getCateByPid(String pid) {
		QueryWrapper<IncreaseCategory> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("pid", pid);
		queryWrapper.orderByDesc("order_num");
		List<IncreaseCategory> list= this.baseMapper.selectList(queryWrapper);
		if(list!=null && list.size()>0) {
			return list.get(0);
		}
		return null;
	}
	
	public List<IncreaseCategory> getCateListByPid(String pid) {
		QueryWrapper<IncreaseCategory> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("pid", pid);
		queryWrapper.orderByAsc("order_num");
		return this.baseMapper.selectList(queryWrapper);
	}
	
	public void importCategory(MultipartFile multipartFile, String bookId) throws IOException {
		if (StringUtils.isBlank(bookId)) {
			return;
		}
		IncreaseBook increaseBook = increaseBookMapper.selectById(bookId);
		String bookName = increaseBook.getBookName();
		// 解析xls文件
		String oriFileName = multipartFile.getOriginalFilename();
		int position = oriFileName.lastIndexOf(".");
		String extName = oriFileName.substring(position);
		Workbook workBook = null;
		if (".xlsx".equals(extName)) {
			workBook = new XSSFWorkbook(multipartFile.getInputStream());
			excelHandler(workBook, bookId);
		} else if (".xls".equals(extName)) {
			workBook = new XSSFWorkbook(multipartFile.getInputStream());
			excelHandler(workBook, bookId);
		}else if (".docx".equals(extName)) {
			wordHandler(multipartFile, bookId);
		}
	}

	public List<CategoryVo> getCategoryTree(String bookId) {
		List<CategoryVo> list = new ArrayList<>();
		IncreaseBook increaseBook = increaseBookMapper.selectById(bookId);
		String bookName = increaseBook.getBookName();
		
		CategoryVo bookVo = new CategoryVo();
		bookVo.setId(bookId);
		bookVo.setPid("0");
		bookVo.setType(1);
		bookVo.setName(bookName);
		bookVo.setLabel(bookName);
		bookVo.setCateLevel(0);
		bookVo.setType(1);
		bookVo.setBookId(bookId);
		List<IncreaseCategory> listCate = getCategory(bookId);
		cateTree(listCate, bookVo);
		list.add(bookVo);
		return list;
	}

	private static void cateTree(List<IncreaseCategory> listCate, CategoryVo category) {
		String id = category.getId();
		List<CategoryVo> childrenList = listCate.stream().filter(item -> {
			String pid = item.getPid();
			if (id.equals(pid)) {
				return true;
			} else {
				return false;
			}
		}).map(item -> {
			CategoryVo vo = new CategoryVo();
			vo.setId(item.getId());
			vo.setName(item.getName());
			vo.setPid(item.getPid());
			vo.setBookId(item.getBookId());
			vo.setCateLevel(item.getCateLevel());
			vo.setOrderNum(item.getOrderNum());
			vo.setLabel(item.getName());
			vo.setType(1);
			return vo;
		}).sorted(Comparator.comparing(CategoryVo::getOrderNum,Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
		category.setChildren(childrenList);

		for (int i = 0; i < childrenList.size(); i++) {
			CategoryVo cateVo = childrenList.get(i);
			cateTree(listCate, cateVo);
		}
	}
	
	private static void cateSelectTree(List<IncreaseCategory> listCate, CategorySelectVo category) {
		String id = category.getMenuId();
		List<CategorySelectVo> childrenList = listCate.stream().filter(item -> {
			String pid = item.getPid();
			if (id.equals(pid)) {
				return true;
			} else {
				return false;
			}
		}).map(item -> {
			CategorySelectVo vo = new CategorySelectVo();
			vo.setMenuId(item.getId());
			vo.setMenuName(item.getName());
			vo.setOrderNum(item.getOrderNum());
			return vo;
		}).sorted(Comparator.comparing(CategorySelectVo::getOrderNum,Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
		category.setChildrenList(childrenList);

		for (int i = 0; i < childrenList.size(); i++) {
			CategorySelectVo cateVo = childrenList.get(i);
			cateSelectTree(listCate, cateVo);
		}
	}
	
	public List<CategorySelectVo> getCategorySelectTree(String bookId) {
		List<IncreaseCategory> listCate = getCategory(bookId);
		
		List<CategorySelectVo> cateList = listCate.stream().filter(item -> {
			String pid = item.getPid();
			if (bookId.equals(pid)) {
				return true;
			} else {
				return false;
			}
		}).map(item -> {
			CategorySelectVo vo = new CategorySelectVo();
			vo.setMenuId(item.getId());
			vo.setMenuName(item.getName());
			vo.setOrderNum(item.getOrderNum());
			return vo;
		}).sorted(Comparator.comparing(CategorySelectVo::getOrderNum,Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
		
		for (int i = 0; i < cateList.size(); i++) {
			CategorySelectVo categorySelectVo= cateList.get(i);
			cateSelectTree(listCate, categorySelectVo);
		}
		IncreaseBook book = increaseBookMapper.selectById(bookId);
		CategorySelectVo vo = new CategorySelectVo();
		vo.setMenuId(book.getId());
		vo.setMenuName(book.getBookName());
		vo.setOrderNum(1);
		vo.setChildrenList(cateList);
		List<CategorySelectVo> result = new ArrayList<>();
		result.add(vo);
		return result;
	}
	
	public void sendDeleteCateData(String id, String userName) {
		IncreaseCategory increaseCategory = new IncreaseCategory();
		increaseCategory.setId(id);
		Map<String, String> syncDataMap = Maps.newHashMap();
		syncDataMap.put("syncPlatform", "increase");
		syncDataMap.put("userName", userName);
		syncDataMap.put("knowledgeLibId", KnowledgeLib.INCREASE_LIB_ID);
		JSONObject termObject = new JSONObject();
		termObject.put("type", KnowledgeSystem.INCREATE_CATE.value);
		termObject.put("option", "delete");
		termObject.put("data", increaseCategory);
		boolean sendFlag2 = RocketMQProducerUtil.sendMessage("increase", "increasebook", increaseCategory.getName(),
				JSON.toJSONString(termObject, SerializerFeature.WriteNullListAsEmpty,
						SerializerFeature.WriteNullStringAsEmpty));
		// 记录同步日志
		syncDataMap.put("knowledgeId", increaseCategory.getId());
		knowledgeSyncStatusService.insertSync(syncDataMap, sendFlag2);
	}
	
	public void excelHandler(Workbook workBook, String bookId) {
		try {
			Sheet sheet = workBook.getSheetAt(0);
			int rowNum = sheet.getLastRowNum();
			for (int i = 1; i <= rowNum; i++) {
				Row row = sheet.getRow(i);
				String qrCodeName = row.getCell(0).getStringCellValue();
				String resourceName = row.getCell(1).getStringCellValue();
				String fileName = row.getCell(2).getStringCellValue();
				String fileExtName = row.getCell(3).getStringCellValue();
				if (StringUtils.isBlank(resourceName)) {
					continue;
				}

				Date nowTime = new Date();
				IncreaseResource resource = new IncreaseResource();
				String id = IdWorker.getIdStr();
				resource.setId(id);
				resource.setName(resourceName);
				resource.setBookId(bookId);

				//this.baseMapper.insert(resource);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				workBook.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 支持最早期的模板导入，后来改了方法废弃
	 * @param workBook
	 * @param bookId
	 */
	public void excelHandlerDrop(Workbook workBook, String bookId) {
		int count = 0;
		try {
			Sheet sheet = workBook.getSheetAt(0);
			Map<String, Integer[]> result = getMergedRegionMap(sheet);
			int rowNum = sheet.getLastRowNum();
			for (int i = 0; i <= rowNum; i++) {
				Row row = sheet.getRow(i);
				String categoryNameStr = "";
				Integer[] categoryPosition = result.get(i + "_" + 0);
				if (categoryPosition != null) {
					Row valueRow = sheet.getRow(categoryPosition[0]);
					categoryNameStr = valueRow.getCell(categoryPosition[1]).getStringCellValue();
				} else {
					categoryNameStr = row.getCell(0).getStringCellValue();
				}
				if (StringUtils.isBlank(categoryNameStr)) {
					continue;
				}
				String[] cateArr = categoryNameStr.split("->");
				String pid = bookId;
				for (int j = 0; j < cateArr.length; j++) {
					String cateName = cateArr[j];
					IncreaseCategory increaseCategory = new IncreaseCategory();
					increaseCategory.setName(cateName);
					increaseCategory.setBookId(bookId);
					increaseCategory.setCateLevel(j + 1);
					increaseCategory.setPid(pid);
				}

				String qrCodeName = "";
				Integer[] qrCodePosition = result.get(i + "_" + 1);
				if (qrCodePosition != null) {
					Row valueRow = sheet.getRow(qrCodePosition[0]);
					qrCodeName = valueRow.getCell(qrCodePosition[1]).getStringCellValue();
				} else {
					qrCodeName = row.getCell(1).getStringCellValue();
				}
				String resourceName = row.getCell(2).getStringCellValue();
				String fileName = row.getCell(3).getStringCellValue();
				String fileExt = row.getCell(4).getStringCellValue();

				count++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				workBook.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public List<IncreaseCategory> getCategory(String bookId) {
		if (StringUtils.isBlank(bookId)) {
			return null;
		}

		QueryWrapper<IncreaseCategory> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("book_id", bookId);
		List<IncreaseCategory> listCate = this.baseMapper.selectList(queryWrapper);
		return listCate;
	}

	public static Map<String, Integer[]> getMergedRegionMap(Sheet sheet) {
		Map<String, Integer[]> result = new HashMap<String, Integer[]>();
		int regionsNum = sheet.getNumMergedRegions();
		for (int i = 0; i < regionsNum; i++) {
			CellRangeAddress range = sheet.getMergedRegion(i);
			int firstColumn = range.getFirstColumn();
			int lastColumn = range.getLastColumn();
			int firstRow = range.getFirstRow();
			int lastRow = range.getLastRow();
			Integer[] mergedRegionPosition = new Integer[] { firstRow, lastColumn };
			for (int j = firstRow; j <= lastRow; j++) {
				for (int j2 = firstColumn; j2 <= lastColumn; j2++) {
					result.put(j + "_" + j2, mergedRegionPosition);
				}
			}
		}
		return result;
	}

	private void wordHandler(MultipartFile multipartFile, String bookId) throws IOException {
		XWPFDocument doc = new XWPFDocument(multipartFile.getInputStream());
		List<XWPFParagraph> list = doc.getParagraphs();
		int level = 0;
		IncreaseCategory preNode = null;
		IncreaseCategory firstLevelCate = null;
		IncreaseCategory secondLevelCate = null;
		String pId = "";
		int firstNum = 1;
		int secondNum = 1;
		int thirdNum = 1;
		for (int i = 0; i < list.size(); i++) {
			XWPFParagraph paragraph = list.get(i);
			String text = paragraph.getText();
			IncreaseCategory category = new IncreaseCategory();
			if (text.indexOf("篇") >= 0) {
				pId = bookId;
				level = 1;
				secondNum = 1;
				category.setOrderNum(firstNum);
				firstNum++;
				firstLevelCate = category;
			} else if (text.indexOf("章") >= 0) {
				pId = firstLevelCate.getId();
				secondLevelCate = category;
				category.setOrderNum(secondNum);
				secondNum++;
				thirdNum = 1;
				level = 2;
			} else if (text.indexOf("节") >= 0) {
				String preCateName = preNode.getName();
				if (preCateName.indexOf("篇") >= 0) {
					pId = firstLevelCate.getId();
				} else {
					pId = secondLevelCate.getId();
				}
				category.setOrderNum(thirdNum);
				thirdNum++;
				level = 3;
			} else {
				continue;
			}
			String id = IdWorker.getId() + "";
			category.setId(id);
			category.setName(text);
			category.setBookId(bookId);
			category.setPid(pId);
			category.setCateLevel(level);
			category.setStatus(1);
			category.setCreateTime(new Date());
			category.setUpdateTime(new Date());
			this.baseMapper.insert(category);
			preNode = category;
		}
	}

	public static void main(String[] args) throws Exception {
		String path = "d:/aa/aa.docx";
		InputStream is = new FileInputStream(path);
		XWPFDocument doc = new XWPFDocument(is);
		List<XWPFParagraph> list = doc.getParagraphs();
		String bookId = "111";
		int level = 0;
		IncreaseCategory preNode = null;
		IncreaseCategory firstLevelCate = null;
		IncreaseCategory secondLevelCate = null;
		String pId = "";
		int firstNum = 1;
		int secondNum = 1;
		int thirdNum = 1;
		List<IncreaseCategory> listCate = new ArrayList<>();
		for (int i = 0; i < list.size(); i++) {
			XWPFParagraph paragraph = list.get(i);
			String text = paragraph.getText();
			IncreaseCategory category = new IncreaseCategory();
			if (text.indexOf("篇") >= 0) {
				pId = bookId;
				level = 1;
				secondNum = 1;
				category.setOrderNum(firstNum);
				firstNum++;
				firstLevelCate = category;
			} else if (text.indexOf("章") >= 0) {
				pId = firstLevelCate.getId();
				secondLevelCate = category;
				category.setOrderNum(secondNum);
				secondNum++;
				thirdNum = 1;
				level = 2;
			} else if (text.indexOf("节") >= 0) {
				String preCateName = preNode.getName();
				if (preCateName.indexOf("篇") >= 0) {
					pId = firstLevelCate.getId();
				} else {
					pId = secondLevelCate.getId();
				}
				category.setOrderNum(thirdNum);
				thirdNum++;
				level = 3;
			} else {
				continue;
			}
			String id = IdWorker.getId() + "";
			category.setId(id);
			category.setName(text);
			category.setBookId(bookId);
			category.setPid(pId);
			category.setCateLevel(level);
			preNode = category;
			listCate.add(category);
			System.out.println("id:" + category.getId() + " pid:" + category.getPid() + " name:" + category.getName()
					+ " orderNum:" + category.getOrderNum());
		}
		CategoryVo vo = new CategoryVo();
		vo.setId(bookId);
		vo.setName("书名");
		vo.setCateLevel(0);
		vo.setPid("0");
		cateTree(listCate, vo);
		String obj = JSON.toJSONString(vo);
		System.out.println(obj);
	}
}
